`include "defines.v"

module axi_interconnect # (
    parameter RW_DATA_WIDTH     = 64,
    parameter RW_ADDR_WIDTH     = 64,
    parameter AXI_DATA_WIDTH    = 64,
    parameter AXI_ADDR_WIDTH    = 64,
    parameter AXI_ID_WIDTH      = 2,
    parameter AXI_USER_WIDTH    = 1 
)(
    input  wire                              clock,
    input  wire                              reset_n,

    // IF Port
    output wire                              if_aw_ready,
    input  wire                              if_aw_valid,
    input  wire [AXI_ADDR_WIDTH-1:0]         if_aw_addr,
    input  wire [2:0]                        if_aw_prot,
    input  wire [AXI_ID_WIDTH-1:0]           if_aw_id,
    input  wire [AXI_USER_WIDTH-1:0]         if_aw_user,
    input  wire [7:0]                        if_aw_len,
    input  wire [2:0]                        if_aw_size,
    input  wire [1:0]                        if_aw_burst,
    input  wire                              if_aw_lock,
    input  wire [3:0]                        if_aw_cache,
    input  wire [3:0]                        if_aw_qos,
    input  wire [3:0]                        if_aw_region,

    output wire                              if_w_ready,
    input  wire                              if_w_valid,
    input  wire [AXI_DATA_WIDTH-1:0]         if_w_data,
    input  wire [AXI_DATA_WIDTH/8-1:0]       if_w_strb,
    input  wire                              if_w_last,
    input  wire [AXI_USER_WIDTH-1:0]         if_w_user,
    
    input  wire                              if_b_ready,
    output wire                              if_b_valid,
    output wire [1:0]                        if_b_resp,
    output wire [AXI_ID_WIDTH-1:0]           if_b_id,
    output wire [AXI_USER_WIDTH-1:0]         if_b_user,

    output wire                              if_ar_ready,
    input  wire                              if_ar_valid,
    input  wire [AXI_ADDR_WIDTH-1:0]         if_ar_addr,
    input  wire [2:0]                        if_ar_prot,
    input  wire [AXI_ID_WIDTH-1:0]           if_ar_id,
    input  wire [AXI_USER_WIDTH-1:0]         if_ar_user,
    input  wire [7:0]                        if_ar_len,
    input  wire [2:0]                        if_ar_size,
    input  wire [1:0]                        if_ar_burst,
    input  wire                              if_ar_lock,
    input  wire [3:0]                        if_ar_cache,
    input  wire [3:0]                        if_ar_qos,
    input  wire [3:0]                        if_ar_region,
    
    input  wire                              if_r_ready,
    output wire                              if_r_valid,
    output wire [1:0]                        if_r_resp,
    output wire [AXI_DATA_WIDTH-1:0]         if_r_data,
    output wire                              if_r_last,
    output wire [AXI_ID_WIDTH-1:0]           if_r_id,
    output wire [AXI_USER_WIDTH-1:0]         if_r_user,

    // Mem Port
    output wire                              mem_aw_ready,
    input  wire                              mem_aw_valid,
    input  wire [AXI_ADDR_WIDTH-1:0]         mem_aw_addr,
    input  wire [2:0]                        mem_aw_prot,
    input  wire [AXI_ID_WIDTH-1:0]           mem_aw_id,
    input  wire [AXI_USER_WIDTH-1:0]         mem_aw_user,
    input  wire [7:0]                        mem_aw_len,
    input  wire [2:0]                        mem_aw_size,
    input  wire [1:0]                        mem_aw_burst,
    input  wire                              mem_aw_lock,
    input  wire [3:0]                        mem_aw_cache,
    input  wire [3:0]                        mem_aw_qos,
    input  wire [3:0]                        mem_aw_region,

    output wire                              mem_w_ready,
    input  wire                              mem_w_valid,
    input  wire [AXI_DATA_WIDTH-1:0]         mem_w_data,
    input  wire [AXI_DATA_WIDTH/8-1:0]       mem_w_strb,
    input  wire                              mem_w_last,
    input  wire [AXI_USER_WIDTH-1:0]         mem_w_user,
    
    input  wire                              mem_b_ready,
    output wire                              mem_b_valid,
    output wire [1:0]                        mem_b_resp,
    output wire [AXI_ID_WIDTH-1:0]           mem_b_id,
    output wire [AXI_USER_WIDTH-1:0]         mem_b_user,

    output wire                              mem_ar_ready,
    input  wire                              mem_ar_valid,
    input  wire [AXI_ADDR_WIDTH-1:0]         mem_ar_addr,
    input  wire [2:0]                        mem_ar_prot,
    input  wire [AXI_ID_WIDTH-1:0]           mem_ar_id,
    input  wire [AXI_USER_WIDTH-1:0]         mem_ar_user,
    input  wire [7:0]                        mem_ar_len,
    input  wire [2:0]                        mem_ar_size,
    input  wire [1:0]                        mem_ar_burst,
    input  wire                              mem_ar_lock,
    input  wire [3:0]                        mem_ar_cache,
    input  wire [3:0]                        mem_ar_qos,
    input  wire [3:0]                        mem_ar_region,

    input  wire                              mem_r_ready,
    output wire                              mem_r_valid,
    output wire [1:0]                        mem_r_resp,
    output wire [AXI_DATA_WIDTH-1:0]         mem_r_data,
    output wire                              mem_r_last,
    output wire [AXI_ID_WIDTH-1:0]           mem_r_id,
    output wire [AXI_USER_WIDTH-1:0]         mem_r_user,

    // Clint Port
    input  wire                              clint_aw_ready,
    output wire                              clint_aw_valid,
    output wire [AXI_ADDR_WIDTH-1:0]         clint_aw_addr,
    output wire [2:0]                        clint_aw_prot,
    output wire [AXI_ID_WIDTH+1:0]           clint_aw_id,
    output wire [AXI_USER_WIDTH-1:0]         clint_aw_user,
    output wire [7:0]                        clint_aw_len,
    output wire [2:0]                        clint_aw_size,
    output wire [1:0]                        clint_aw_burst,
    output wire                              clint_aw_lock,
    output wire [3:0]                        clint_aw_cache,
    output wire [3:0]                        clint_aw_qos,
    output wire [3:0]                        clint_aw_region,

    input  wire                              clint_w_ready,
    output wire                              clint_w_valid,
    output wire [AXI_DATA_WIDTH-1:0]         clint_w_data,
    output wire [AXI_DATA_WIDTH/8-1:0]       clint_w_strb,
    output wire                              clint_w_last,
    output wire [AXI_USER_WIDTH-1:0]         clint_w_user,
    
    output wire                              clint_b_ready,
    input  wire                              clint_b_valid,
    input  wire [1:0]                        clint_b_resp,
    input  wire [AXI_ID_WIDTH+1:0]           clint_b_id,
    input  wire [AXI_USER_WIDTH-1:0]         clint_b_user,

    input  wire                              clint_ar_ready,
    output wire                              clint_ar_valid,
    output wire [AXI_ADDR_WIDTH-1:0]         clint_ar_addr,
    output wire [2:0]                        clint_ar_prot,
    output wire [AXI_ID_WIDTH+1:0]           clint_ar_id,
    output wire [AXI_USER_WIDTH-1:0]         clint_ar_user,
    output wire [7:0]                        clint_ar_len,
    output wire [2:0]                        clint_ar_size,
    output wire [1:0]                        clint_ar_burst,
    output wire                              clint_ar_lock,
    output wire [3:0]                        clint_ar_cache,
    output wire [3:0]                        clint_ar_qos,
    output wire [3:0]                        clint_ar_region,
    
    output wire                              clint_r_ready,
    input  wire                              clint_r_valid,
    input  wire [1:0]                        clint_r_resp,
    input  wire [AXI_DATA_WIDTH-1:0]         clint_r_data,
    input  wire                              clint_r_last,
    input  wire [AXI_ID_WIDTH+1:0]           clint_r_id,
    input  wire [AXI_USER_WIDTH-1:0]         clint_r_user,

    // Advanced eXtensible Interface
    input  wire                              axi_aw_ready,
    output wire                              axi_aw_valid,
    output wire [AXI_ADDR_WIDTH-1:0]         axi_aw_addr,
    output wire [2:0]                        axi_aw_prot,
    output wire [AXI_ID_WIDTH+1:0]           axi_aw_id,
    output wire [AXI_USER_WIDTH-1:0]         axi_aw_user,
    output wire [7:0]                        axi_aw_len,
    output wire [2:0]                        axi_aw_size,
    output wire [1:0]                        axi_aw_burst,
    output wire                              axi_aw_lock,
    output wire [3:0]                        axi_aw_cache,
    output wire [3:0]                        axi_aw_qos,
    output wire [3:0]                        axi_aw_region,

    input  wire                              axi_w_ready,
    output wire                              axi_w_valid,
    output wire [AXI_DATA_WIDTH-1:0]         axi_w_data,
    output wire [AXI_DATA_WIDTH/8-1:0]       axi_w_strb,
    output wire                              axi_w_last,
    output wire [AXI_USER_WIDTH-1:0]         axi_w_user,
    
    output wire                              axi_b_ready,
    input  wire                              axi_b_valid,
    input  wire [1:0]                        axi_b_resp,
    input  wire [AXI_ID_WIDTH+1:0]           axi_b_id,
    input  wire [AXI_USER_WIDTH-1:0]         axi_b_user,

    input  wire                              axi_ar_ready,
    output wire                              axi_ar_valid,
    output wire [AXI_ADDR_WIDTH-1:0]         axi_ar_addr,
    output wire [2:0]                        axi_ar_prot,
    output wire [AXI_ID_WIDTH+1:0]           axi_ar_id,
    output wire [AXI_USER_WIDTH-1:0]         axi_ar_user,
    output wire [7:0]                        axi_ar_len,
    output wire [2:0]                        axi_ar_size,
    output wire [1:0]                        axi_ar_burst,
    output wire                              axi_ar_lock,
    output wire [3:0]                        axi_ar_cache,
    output wire [3:0]                        axi_ar_qos,
    output wire [3:0]                        axi_ar_region,
    
    output wire                              axi_r_ready,
    input  wire                              axi_r_valid,
    input  wire [1:0]                        axi_r_resp,
    input  wire [AXI_DATA_WIDTH-1:0]         axi_r_data,
    input  wire                              axi_r_last,
    input  wire [AXI_ID_WIDTH+1:0]           axi_r_id,
    input  wire [AXI_USER_WIDTH-1:0]         axi_r_user 
);

    //----------Arbiter----------//
    wire                              arbiter_aw_ready;
    wire                              arbiter_aw_valid;
    wire [AXI_ADDR_WIDTH-1:0]         arbiter_aw_addr;
    wire [2:0]                        arbiter_aw_prot;
    wire [AXI_ID_WIDTH+1:0]           arbiter_aw_id;
    wire [AXI_USER_WIDTH-1:0]         arbiter_aw_user;
    wire [7:0]                        arbiter_aw_len;
    wire [2:0]                        arbiter_aw_size;
    wire [1:0]                        arbiter_aw_burst;
    wire                              arbiter_aw_lock;
    wire [3:0]                        arbiter_aw_cache;
    wire [3:0]                        arbiter_aw_qos;
    wire [3:0]                        arbiter_aw_region;
    wire                              arbiter_w_ready;
    wire                              arbiter_w_valid;
    wire [AXI_DATA_WIDTH-1:0]         arbiter_w_data;
    wire [AXI_DATA_WIDTH/8-1:0]       arbiter_w_strb;
    wire                              arbiter_w_last;
    wire [AXI_USER_WIDTH-1:0]         arbiter_w_user;
    wire                              arbiter_b_ready;
    wire                              arbiter_b_valid;
    wire [1:0]                        arbiter_b_resp;
    wire [AXI_ID_WIDTH+1:0]           arbiter_b_id;
    wire [AXI_USER_WIDTH-1:0]         arbiter_b_user;
    wire                              arbiter_ar_ready;
    wire                              arbiter_ar_valid;
    wire [AXI_ADDR_WIDTH-1:0]         arbiter_ar_addr;
    wire [2:0]                        arbiter_ar_prot;
    wire [AXI_ID_WIDTH+1:0]           arbiter_ar_id;
    wire [AXI_USER_WIDTH-1:0]         arbiter_ar_user;
    wire [7:0]                        arbiter_ar_len;
    wire [2:0]                        arbiter_ar_size;
    wire [1:0]                        arbiter_ar_burst;
    wire                              arbiter_ar_lock;
    wire [3:0]                        arbiter_ar_cache;
    wire [3:0]                        arbiter_ar_qos;
    wire [3:0]                        arbiter_ar_region;
    wire                              arbiter_r_ready;
    wire                              arbiter_r_valid;
    wire [1:0]                        arbiter_r_resp;
    wire [AXI_DATA_WIDTH-1:0]         arbiter_r_data;
    wire                              arbiter_r_last;
    wire [AXI_ID_WIDTH+1:0]           arbiter_r_id;
    wire [AXI_USER_WIDTH-1:0]         arbiter_r_user;

    // AW Channel
    assign if_aw_ready              =           0;
    assign mem_aw_ready             =           arbiter_aw_ready;
    assign arbiter_aw_valid         =           mem_aw_valid;
    assign arbiter_aw_addr          =           mem_aw_addr;
    assign arbiter_aw_prot          =           mem_aw_prot;
    assign arbiter_aw_id            =           { 2'b01 , mem_aw_id };
    assign arbiter_aw_user          =           mem_aw_user;
    assign arbiter_aw_len           =           mem_aw_len;
    assign arbiter_aw_size          =           mem_aw_size;
    assign arbiter_aw_burst         =           mem_aw_burst;
    assign arbiter_aw_lock          =           mem_aw_lock;
    assign arbiter_aw_cache         =           mem_aw_cache;
    assign arbiter_aw_qos           =           mem_aw_qos;
    assign arbiter_aw_region        =           mem_aw_region;

    // W Channel
    assign if_w_ready               =           0;
    assign mem_w_ready              =           arbiter_w_ready;
    assign arbiter_w_valid          =           mem_w_valid;
    assign arbiter_w_data           =           mem_w_data;
    assign arbiter_w_strb           =           mem_w_strb;
    assign arbiter_w_last           =           mem_w_last;
    assign arbiter_w_user           =           mem_w_user;

    // B Channel
    assign arbiter_b_ready          =           mem_b_ready;
    assign mem_b_valid              =           arbiter_b_valid;
    assign mem_b_resp               =           arbiter_b_resp;
    assign mem_b_id                 =           arbiter_b_id[1:0];
    assign mem_b_user               =           arbiter_b_user;
    assign if_b_valid               =           0;
    assign if_b_resp                =           0;
    assign if_b_id                  =           0;

    // AR Channel
    assign mem_ar_ready             =           mem_ar_valid  ?  arbiter_ar_ready       :    0                     ;
    assign if_ar_ready              =           mem_ar_valid  ?  0                      :    arbiter_ar_ready      ;
    assign arbiter_ar_valid         =           mem_ar_valid  ?  mem_ar_valid           :    if_ar_valid           ;
    assign arbiter_ar_addr          =           mem_ar_valid  ?  mem_ar_addr            :    if_ar_addr            ;
    assign arbiter_ar_prot          =           mem_ar_valid  ?  mem_ar_prot            :    if_ar_prot            ;
    assign arbiter_ar_id            =           mem_ar_valid  ?  { 2'b01 , mem_ar_id }  :    { 2'b00 , if_ar_id }  ;
    assign arbiter_ar_user          =           mem_ar_valid  ?  mem_ar_user            :    if_ar_user            ;
    assign arbiter_ar_len           =           mem_ar_valid  ?  mem_ar_len             :    if_ar_len             ;
    assign arbiter_ar_size          =           mem_ar_valid  ?  mem_ar_size            :    if_ar_size            ;
    assign arbiter_ar_burst         =           mem_ar_valid  ?  mem_ar_burst           :    if_ar_burst           ;
    assign arbiter_ar_lock          =           mem_ar_valid  ?  mem_ar_lock            :    if_ar_lock            ;
    assign arbiter_ar_cache         =           mem_ar_valid  ?  mem_ar_cache           :    if_ar_cache           ;
    assign arbiter_ar_qos           =           mem_ar_valid  ?  mem_ar_qos             :    if_ar_qos             ;
    assign arbiter_ar_region        =           mem_ar_valid  ?  mem_ar_region          :    if_ar_region          ;

    // R Channel
    assign arbiter_r_ready          =           (arbiter_r_id[3:2] == 1)  ?  mem_r_ready       :    if_r_ready         ;
    assign mem_r_valid              =           (arbiter_r_id[3:2] == 1)  ?  arbiter_r_valid   :    0                  ;
    assign if_r_valid               =           (arbiter_r_id[3:2] == 1)  ?  0                 :    arbiter_r_valid    ;
    assign mem_r_resp               =           (arbiter_r_id[3:2] == 1)  ?  arbiter_r_resp    :    0                  ;
    assign if_r_resp                =           (arbiter_r_id[3:2] == 1)  ?  0                 :    arbiter_r_resp     ;
    assign mem_r_data               =           (arbiter_r_id[3:2] == 1)  ?  arbiter_r_data    :    0                  ;
    assign if_r_data                =           (arbiter_r_id[3:2] == 1)  ?  0                 :    arbiter_r_data     ;
    assign mem_r_last               =           (arbiter_r_id[3:2] == 1)  ?  arbiter_r_last    :    0                  ;
    assign if_r_last                =           (arbiter_r_id[3:2] == 1)  ?  0                 :    arbiter_r_last     ;
    assign mem_r_id                 =           (arbiter_r_id[3:2] == 1)  ?  arbiter_r_id[1:0] :    0                  ;
    assign if_r_id                  =           (arbiter_r_id[3:2] == 1)  ?  0                 :    arbiter_r_id[1:0]  ;
    assign mem_r_user               =           (arbiter_r_id[3:2] == 1)  ?  arbiter_r_user    :    0                  ;
    assign if_r_user                =           (arbiter_r_id[3:2] == 1)  ?  0                 :    arbiter_r_user     ;


    //----------Router----------//
    reg  clint_r_access;
    wire clint_r_access_en  = arbiter_ar_valid & (({ arbiter_ar_addr[63:3] , 3'b0 } == `mtime_addr) | ({ arbiter_ar_addr[63:3] , 3'b0 } == `mtimecmp_addr));
    wire clint_r_access_rst = clint_r_valid & clint_r_ready & clint_r_last;

    always @(posedge clock) begin
        if(~reset_n)                clint_r_access <= 1'b0;
        else if(clint_r_access_rst) clint_r_access <= 1'b0;
        else if(clint_r_access_en)  clint_r_access <= 1'b1;
        else                        clint_r_access <= clint_r_access;
    end

    reg  clint_w_access;
    wire clint_w_access_en  = arbiter_aw_valid & (({ arbiter_aw_addr[63:3] , 3'b0 } == `mtime_addr) | ({ arbiter_aw_addr[63:3] , 3'b0 } == `mtimecmp_addr));
    wire clint_w_access_rst = clint_b_valid & clint_b_ready;

    always @(posedge clock) begin
        if(~reset_n)                clint_w_access <= 1'b0;
        else if(clint_w_access_rst) clint_w_access <= 1'b0;
        else if(clint_w_access_en)  clint_w_access <= 1'b1;
        else                        clint_w_access <= clint_w_access;
    end

    // Clint Port
    // AW Channel
    assign arbiter_aw_ready       =           clint_w_access_en  ?  clint_aw_ready    :  axi_aw_ready  ;
    assign clint_aw_valid         =           clint_w_access_en  ?  arbiter_aw_valid  :  0             ;
    assign clint_aw_addr          =           arbiter_aw_addr;
    assign clint_aw_prot          =           arbiter_aw_prot;
    assign clint_aw_id            =           arbiter_aw_id;
    assign clint_aw_user          =           arbiter_aw_user;
    assign clint_aw_len           =           arbiter_aw_len;
    assign clint_aw_size          =           arbiter_aw_size;
    assign clint_aw_burst         =           arbiter_aw_burst;
    assign clint_aw_lock          =           arbiter_aw_lock;
    assign clint_aw_cache         =           arbiter_aw_cache;
    assign clint_aw_qos           =           arbiter_aw_qos;
    assign clint_aw_region        =           arbiter_aw_region;

    // W Channel
    assign arbiter_w_ready        =           clint_w_access  ?  clint_w_ready    :  axi_w_ready  ;
    assign clint_w_valid          =           clint_w_access  ?  arbiter_w_valid  :  0            ;
    assign clint_w_data           =           arbiter_w_data;
    assign clint_w_strb           =           arbiter_w_strb;
    assign clint_w_last           =           arbiter_w_last;
    assign clint_w_user           =           arbiter_w_user;

    // B Channel
    assign clint_b_ready          =           clint_w_access ?  arbiter_b_ready  :  0            ;
    assign arbiter_b_valid        =           clint_w_access ?  clint_b_valid    :  axi_b_valid  ;
    assign arbiter_b_resp         =           clint_w_access ?  clint_b_resp     :  axi_b_resp   ;
    assign arbiter_b_id           =           clint_w_access ?  clint_b_id       :  axi_b_id     ;
    assign arbiter_b_user         =           clint_w_access ?  clint_b_user     :  axi_b_user   ;

    // AR Channel
    assign arbiter_ar_ready       =           clint_r_access_en  ?  clint_ar_ready    :  axi_ar_ready  ;
    assign clint_ar_valid         =           clint_r_access_en  ?  arbiter_ar_valid  :  0             ;
    assign clint_ar_addr          =           arbiter_ar_addr    ;
    assign clint_ar_prot          =           arbiter_ar_prot    ;
    assign clint_ar_id            =           arbiter_ar_id      ;
    assign clint_ar_user          =           arbiter_ar_user    ;
    assign clint_ar_len           =           arbiter_ar_len     ;
    assign clint_ar_size          =           arbiter_ar_size    ;
    assign clint_ar_burst         =           arbiter_ar_burst   ;
    assign clint_ar_lock          =           arbiter_ar_lock    ;
    assign clint_ar_cache         =           arbiter_ar_cache   ;
    assign clint_ar_qos           =           arbiter_ar_qos     ;
    assign clint_ar_region        =           arbiter_ar_region  ;

    // R Channel
    assign clint_r_ready          =           clint_r_access  ?  arbiter_r_ready  :  0            ;
    assign arbiter_r_valid        =           clint_r_access  ?  clint_r_valid    :  axi_r_valid  ;
    assign arbiter_r_resp         =           clint_r_access  ?  clint_r_resp     :  axi_r_resp   ;
    assign arbiter_r_data         =           clint_r_access  ?  clint_r_data     :  axi_r_data   ;
    assign arbiter_r_last         =           clint_r_access  ?  clint_r_last     :  axi_r_last   ;
    assign arbiter_r_id           =           clint_r_access  ?  clint_r_id       :  axi_r_id     ;
    assign arbiter_r_user         =           clint_r_access  ?  clint_r_user     :  axi_r_user   ;

    // Advanced eXtensible Interface
    // AW Channel
    assign axi_aw_valid           =           clint_w_access_en  ?  0  :  arbiter_aw_valid  ;
    assign axi_aw_addr            =           arbiter_aw_addr;
    assign axi_aw_prot            =           arbiter_aw_prot;
    assign axi_aw_id              =           arbiter_aw_id;
    assign axi_aw_user            =           arbiter_aw_user;
    assign axi_aw_len             =           arbiter_aw_len;
    assign axi_aw_size            =           arbiter_aw_size;
    assign axi_aw_burst           =           arbiter_aw_burst;
    assign axi_aw_lock            =           arbiter_aw_lock;
    assign axi_aw_cache           =           arbiter_aw_cache;
    assign axi_aw_qos             =           arbiter_aw_qos;
    assign axi_aw_region          =           arbiter_aw_region;

    // W Channel
    assign axi_w_valid            =           clint_w_access     ?  0  :  arbiter_w_valid  ;
    assign axi_w_data             =           arbiter_w_data;
    assign axi_w_strb             =           arbiter_w_strb;
    assign axi_w_last             =           arbiter_w_last;
    assign axi_w_user             =           arbiter_w_user;

    // B Channel
    assign axi_b_ready            =           clint_w_access     ?  0  :  arbiter_b_ready  ;

    // AR Channel
    assign axi_ar_valid           =           clint_r_access_en  ?  0  :  arbiter_ar_valid  ;
    assign axi_ar_addr            =           arbiter_ar_addr    ;
    assign axi_ar_prot            =           arbiter_ar_prot    ;
    assign axi_ar_id              =           arbiter_ar_id      ;
    assign axi_ar_user            =           arbiter_ar_user    ;
    assign axi_ar_len             =           arbiter_ar_len     ;
    assign axi_ar_size            =           arbiter_ar_size    ;
    assign axi_ar_burst           =           arbiter_ar_burst   ;
    assign axi_ar_lock            =           arbiter_ar_lock    ;
    assign axi_ar_cache           =           arbiter_ar_cache   ;
    assign axi_ar_qos             =           arbiter_ar_qos     ;
    assign axi_ar_region          =           arbiter_ar_region  ;

    // R Channel
    assign axi_r_ready            =           clint_r_access     ?  0  :  arbiter_r_ready  ;

endmodule